package tenumn.energytech.registrys.machine;

import io.github.uicdb.liba.api.register.BlockEntityTypeHolder;
import io.github.uicdb.liba.api.register.BlockHolder;
import io.github.uicdb.liba.api.register.LazyRegistry;
import io.github.uicdb.liba.api.register.MenuHolder;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Tiers;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.generators.BlockStateProvider;
import net.minecraftforge.client.model.generators.ConfiguredModel;
import net.minecraftforge.client.model.generators.ModelFile;
import net.minecraftforge.client.model.generators.VariantBlockStateBuilder;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import tenumn.energytech.EnergyTech;
import tenumn.energytech.registrys.TierRegistry;
import tenumn.energytech.registrys.machine.heart.*;

import java.util.function.BiConsumer;

public class MachineRegistry {
    public static final LazyRegistry registry = EnergyTech.LAZY_REGISTRY;

    /*****************燃烧室*************************/
    public static final BlockHolder<StoneBurnerBlock> stoneBurner = registry.block("stone_burner", StoneBurnerBlock::new)
            .state(orientableWithBottom("front", "side", "side"))
            .name("zh_cn", "石勒制燃烧室")
            .tier(TierRegistry.FLINT)
            .pickaxe()
            .build();
    public static final BlockEntityTypeHolder<StoneBurnerBlockEntity> beStoneBurner = registry.blockEntity("stone_burner", StoneBurnerBlockEntity::new)
            .withBlocks(stoneBurner)
            .build();
    public static final BlockHolder<SteelBurnerBlock> steelBurner = registry.block("steel_burner", SteelBurnerBlock::new)
            .state(orientableWithBottom("front", "side", "side"))
            .name("zh_cn", "钢焖燃烧室")
            .tier(TierRegistry.STEEL)
            .pickaxe()
            .build();
    public static final BlockEntityTypeHolder<SteelBurnerBlockEntity> beSteelBurner = registry.blockEntity("steel_burner", SteelBurnerBlockEntity::new)
            .withBlocks(steelBurner)
            .build();
    public static final BlockHolder<ElectricHeaterBlock> electricHeater=registry.block("electric_heater",ElectricHeaterBlock::new)
            .tier(Tiers.IRON)
            .pickaxe()
            .state(orientableWithBottom("front", "side", "side"))
            .name("zh_cn", "电子跃迁势能热转换构造器v0.1")
            .build();
    public static final BlockEntityTypeHolder<ElectricHeaterBlockEntity> electricHeaterBlockEntity=registry.blockEntity("electric_heater",ElectricHeaterBlockEntity::new)
            .withBlocks(electricHeater)
            .build();
    public static final BlockHolder<SolarHeaterBlock> solarHeater=registry.block("solar_heater",SolarHeaterBlock::new)
            .tier(Tiers.IRON)
            .pickaxe()
            .state(orientableWithBottom("front", "side", "side"))
            .name("zh_cn", "主的祝福")
            .build();
    public static final BlockEntityTypeHolder<SolarHeaterBlockEntity> solarHeaterBlockEntity=registry.blockEntity("solar_heater",SolarHeaterBlockEntity::new)
            .withBlocks(solarHeater)
            .build();

    /*************************************************************/
    public static final BlockHolder<SteamEngineBlock> blockSteamEngine = registry.block("steam_engine", SteamEngineBlock::new)
            .propertie(properties -> properties.destroyTime(5))
            .pickaxe()//工具类型，可同时存在不同类型
            .state(orientableWithBottom("front", "side", "side"))//可旋转模型
            .name("zh_cn", "蒸汽引擎")//不用写en_us，自动会把注册名首字母大写
            .tier(Tiers.IRON)//工具等级
            .build();
    public static final BlockEntityTypeHolder<SteamEngineBlockEntity> beSteamEngine = registry.blockEntity("steam_engine", SteamEngineBlockEntity::new)
            .withBlocks(blockSteamEngine)//不绑定方块就没有tick事件（来自mojang的奇妙设定）
            .build();
    //注册MenuType后不要忘记在clientSetup里面绑定Screen
    public static final MenuHolder<SteamEngineMenu> menuSteamEngine = registry.menu("steam_engine", SteamEngineMenu::new);
    public static final BlockHolder<SteamBoilerBlock> steamBoilerBlock = registry.block("steam_boiler", SteamBoilerBlock::new)
            .tier(Tiers.STONE)
            .propertie(BlockBehaviour.Properties::noOcclusion)
            .state(useModel())
            .name("zh_cn", "蒸汽锅锅炉")
            .pickaxe()
            .build();
    public static final BlockEntityTypeHolder<SteamBoilerBlockEntity> steamBoilerBlockEntity = registry.blockEntity("steam_boiler", SteamBoilerBlockEntity::new)
            .withBlocks(steamBoilerBlock)
            .build();
    public static final BlockHolder<SmashBlock> smashBlock = registry.block("smash_block", SmashBlock::new)
            .tier(TierRegistry.STEEL)
            .propertie(BlockBehaviour.Properties::noOcclusion)
            .state(orientableWithBottom("front", "side", "side"))
            .name("zh_cn", "粉碎机")
            .pickaxe()
            .build();
    public static final BlockEntityTypeHolder<SmashBlockEntity> smashBlockEntity = registry.blockEntity("smash_block", SmashBlockEntity::new)
            .withBlocks(smashBlock)
            .build();

    public static void initialize() {
    }

    /**
     * 提供一个可旋转的机器模型
     */
    public static BiConsumer<BlockStateProvider, BlockHolder<?>> orientableWithBottom(String front, String bottom, String top) {
        String prefix = EnergyTech.ID + ":block/";
        return (provider, blockHolder) -> {
            var model = provider.models()
                    .orientableWithBottom(blockHolder.get().getRegistryName().getPath()
                            , new ResourceLocation(EnergyTech.ID, "block/side")
                            , new ResourceLocation(prefix + front)
                            , new ResourceLocation(prefix + bottom)
                            , new ResourceLocation(prefix + top));
            VariantBlockStateBuilder builder = provider.getVariantBuilder(blockHolder.get());
            builder.forAllStates(state -> {
                var res = new ConfiguredModel(model, 0, getRotY(state.getValue(BlockStateProperties.HORIZONTAL_FACING)), true);
                return new ConfiguredModel[]{res};
            });
        };
    }
    public static BiConsumer<BlockStateProvider, BlockHolder<?>> useModel(){
        return (provider, blockHolder) -> {
            var res = blockHolder.get().getRegistryName();
            provider.simpleBlock(blockHolder.get(), new ModelFile.UncheckedModelFile(new ResourceLocation(res.getNamespace(), "block/" + res.getPath())));
        };
    }
    /**
     * 根据方块方向提供旋转角度
     */
    private static int getRotY(Direction direction) {
        return switch (direction) {
            case EAST -> 90;
            case SOUTH -> 180;
            case WEST -> 270;
            default -> 0;
        };
    }

    /**
     * 绑定渲染相关内容，如方块渲染类型，实体方块自定义渲染，MenuType和Screen的绑定等等
     */
    @OnlyIn(Dist.CLIENT)
    public static void clientSetup(FMLClientSetupEvent event) {
        event.enqueueWork(() -> {
            MenuScreens.register(menuSteamEngine.get(), SteamEngineScreen::new);
        });
    }
}
